# -*- coding: utf_8 -*-
# @Create   : 2021/9/1 11:15
# @Author   : yh
# @Remark   : 巡检任务model层
import time
from enum import Enum
from typing import List, Union

from mxsoftpy import Model
from pydantic import constr, validator

from model.common.VideoManage.VideoQuality.inspection_plan import TestItemsSubModel
from model.public.base import MxBaseModel, MxUpdateBaseModel
from utils.parser.fields import check_time_str


class TaskStateModel(str, Enum):
    """
    任务状态模型
    """
    not_begin = '0'  # 未开始
    ongoing = '1'    # 进行中
    ended = '2'      # 已结束
    all = ''         # 全部


class InspectionTaskBeginModel(MxUpdateBaseModel):
    """
    巡检任务更新模型（用于开始执行巡检任务更新执行情况）
    """
    task_state: TaskStateModel = TaskStateModel.ongoing.value  # 任务状态，默认未进行中


class InspectionTaskEndModel(InspectionTaskBeginModel):
    """
    巡检任务更新模型（用于巡检任务完成后更新执行情况）
    """
    device_num: int = -1                               # 设备数量
    test_num: int = -1                                 # 测试项目数量
    normal_num: int = -1                               # 正常项目数量
    fault_num: int = -1                                # 故障项目数量
    failed_num: int = -1                               # 失败项目数量
    end_time: int = int(time.time())                   # 任务结束时间
    task_state: TaskStateModel = TaskStateModel.ended.value  # 任务状态 0 未开始、1 进行中、2 已结束


class InspectionTaskModel(MxBaseModel):
    """
    巡检任务模型
    """
    name: constr(min_length=1, max_length=50)              # 任务名称
    inspection_plan_code: str = '0'                        # 所属计划code
    time_task_code: str = '0'                              # 所属定时任务code
    principal: str                                               # 负责人
    task_state: TaskStateModel = TaskStateModel.not_begin.value  # 任务状态 0 未开始、1 进行中、2 已结束
    videos: str                                                  # 此任务所包含的视频（多个使用逗号分割）
    TestItems: List[TestItemsSubModel]                     # 检测项目
    state: int = 1                                         # 状态 0：删除、1：在用
    begin_time: Union[int, str]                            # 任务开始时间
    desc: constr(max_length=200) = ''                      # 备注

    @validator('begin_time')
    def check_begin_time(cls, value):
        """
        如果传递时间字符串，校验时间字符串是否符合时间格式，否则当作时间戳
        """
        if isinstance(value, str):
            if not value.isdigit():
                value = check_time_str(value)
        return value


class InspectionTaskSelectModel(Model):
    """
    巡检任务查询参数模型（巡检任务查询时、所有的查询参数）
    """
    begin_time: str = ''                             # 开始时间
    end_time: str = ''                               # 结束时间
    name: constr(max_length=50) = ''                 # 任务名称
    state: Union[int, str, None] = ''                # 数据状态  默认获取所有
    task_state: TaskStateModel = TaskStateModel.all  # 任务状态 0 未开始、1 进行中、2 已结束
    plan_code: str = ''                              # 所属巡检计划code

    @validator('begin_time')
    def check_start_time(cls, value):
        return check_time_str(value if value else '1999-10-01 00:00')

    @validator('end_time')
    def check_end_time(cls, value):
        return check_time_str(value) if value else int(time.time()) + 60*60*24*365


class InspectionTaskResponseModel(Model):
    """
    巡检任务返回参数模型（用于未检测任务的检测数据默认值）
    """
    begin_time: str                                  # 开始时间
    device_num: int = ""                             # 设备数量
    failed_num: int = ""                             # 失败项目数量
    fault_num: int = ""                              # 故障项目数量
    inspection_plan_code: str                        # 所属计划code
    name: str                                        # 任务名称
    normal_num: int = ""                             # 正常项目数量
    principal: str                                   # 负责人
    state: int = 1                                   # 状态 0：删除、1：在用
    task_state: str                                  # 任务状态 0 未开始、1 进行中、2 已结束
    test_num: int = ""                               # 测试项目数量
    end_time: str = ""                               # 任务结束时间
    TestItems: dict                                  # 检测项目
    task_code: str                                   # 任务code
    inspection_plan_name: str                        # 所属计划名称

